home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-04-10 | 28.1 KB | 850 lines | [TEXT/MPS ] |
- /*---------------------------------------------------------------------------
- FILENAME
- SCPrinterStatus.c
-
- DESCRIPTION
- This file contains the routines which manage checking the status of the
- SC printer and alerting the user (as needed) to problems that might arise.
-
- COPYRIGHT
- Copyright Apple Computer, Inc. 1989-1992
- All rights reserved.
-
- INTERFACE ROUTINES:
- SetPrinterProblemStatResIndex
- SetPrinterProblemStatResID
- FindPrinterProblem
- ResolvePrinterProblem
-
- --------------------------------------------------------------------------- */
-
- // Include the standard Mac header files
- #include "MacIncludes.h"
-
- // Include the new QuickDraw GX graphics header files
- #include <graphics routines.h>
- #include <graphics libraries.h>
- #include <math routines.h>
-
- // Include the required Printing Manager header files
- #include <PrintingManager.h>
- #include <PrintingMessages.h>
- #include <PrintingDrivers.h>
- #include <Collections.h>
- #include <Messages.h>
- #include <PrintingResTypes.h>
- #include <PrintingErrors.h>
-
- #include <GXExceptions.h>
-
- // Include the internal driver constants and types used by this module
- #include "LaserSCResources.h"
- #include "LaserSCIntf.h"
- #include "SCPrinterStatus.h"
-
-
- /***************************************************************************************
- * INTERNAL ROUTINES *
- ***************************************************************************************/
-
- /****************************************************************************************
-
- WaitForABit
-
-
- function:
- This routine is called to pause for a small amount of time and
- give up idle time to the foreground.
-
- parameters:
- None
- returns:
- None
-
- ****************************************************************************************/
- void WaitForABit(void)
- {
- long nextQuery = TickCount() + kQueryRate;
- while (nextQuery > TickCount())
- (void)GXJobIdle();
- }
- /* WaitForABit */
-
- /****************************************************************************************
-
- CheckEngineStatus1Bits
-
-
- function:
- This routine is called to examine the Engine Status 1 Bits in the status
- data returned from the printer. The routine examines these bits to
- determine if any of the following problems exists on the printer:
-
- Fixing assembly has malfunctioned
- Laser has malfunctioned
- Polygon motor has malfunctioned
- Serial communications have malfunctioned
- Some other hardware problem has occurred
-
- If one of these problems is encountered, the problemStatResIndex parameter
- returns an index into a 'stat' resource of the status that reflects the
- printer's current status.
-
- parameters:
- pSenseData Printer status info. received from the printer
- problemStatResIndex returns the 'stat' index of the printer's current error
- status if an error was encountered
- returns:
- None
-
- ****************************************************************************************/
- void CheckEngineStatus1Bits(SCSenseDataPtr pSenseData, short *problemStatResIndex)
- {
- if ( FixingMalfunction(pSenseData) )
- *problemStatResIndex = kBadPrintFixStatIdx;
- else
- if ( LaserMalfunction(pSenseData) )
- *problemStatResIndex = kBadLaserStatIdx;
- else
- if ( PolyMalfunction(pSenseData) )
- *problemStatResIndex = kBadPolyMotorStatIdx;
- else
- if ( SerialMalfunction(pSenseData) )
- *problemStatResIndex = kBadSerialStatIdx;
- else
- *problemStatResIndex = kGenericBadHdwareStatIdx;
- }
- /* CheckEngineStatus1Bits */
-
-
- /****************************************************************************************
-
- CheckEngineStatus0Bits
-
-
- function:
- This routine is called to examine the Engine Status 0 Bits in the status
- data returned from the printer. The routine examines these bits to
- determine if any of the following problems exists on the printer:
-
- No toner cartridge/improperly installed
- No paper tray/manual feed and no paper in printer
- No paper cartridge/improperly installed
- Paper jam
- Upper door of printer is open
- Test printing is underway
- Fixing unit is being heated
-
- If one of these problems is encountered, the problemStatResIndex parameter
- returns an index into a 'stat' resource of the status that reflects the
- printer's current status.
-
- parameters:
- pSenseData Printer status info. received from the printer
- problemStatResIndex returns the 'stat' index of the printer's current error
- status if an error was encountered
- returns:
- None
-
- ****************************************************************************************/
- void CheckEngineStatus0Bits(SCSenseDataPtr pSenseData, short *problemStatResIndex)
- {
- if ( NoToner(pSenseData) )
- *problemStatResIndex = kBadTonerCartridgeStatIdx;
- else
- if ( NoPaperTray(pSenseData) )
- *problemStatResIndex = kBadPaperCartridgeStatIdx;
- else
- if ( NoPaper(pSenseData) )
- *problemStatResIndex = kOutOfPaperStatIdx;
- else
- if ( PaperJam(pSenseData) )
- *problemStatResIndex = kPaperJamStatIdx;
- else
- if ( DoorOpen(pSenseData) )
- *problemStatResIndex = kOpenDoorStatIdx;
- else
- if ( TestPrint(pSenseData) )
- *problemStatResIndex = kPrintTestStatIdx;
- else
- if ( HeatingFixUnit(pSenseData) )
- *problemStatResIndex = kHeatFixingUnitStatIdx;
- }
- /* CheckEngineStatus0Bits */
-
-
- /****************************************************************************************
-
- SetStatusIndex
-
-
- function:
- This routine is called to initialize the statResId and statResIndex fields
- in the status record referenced by pStatus. If the dontAlert parameter
- is true, the we make sure that only informationalStatus 'stat' resources
- will be referenced by pStatus.
-
- parameters:
- pStatus Status record used to alert the user to printer problems
- currentProblem the 'stat' ID and res index of the printer's current status
- manualFeed T => doing manual feed job; F => doing auto-feed
- dontAlert T => we don't want to set the status record's statResId and
- statResIndex to a value which would cause the PFE to display
- an alert dialog to the user. When true, we make sure only
- informationalStatus 'stat' resources will be referenced by
- pStatus.
-
- returns:
- None
-
- ****************************************************************************************/
- void SetStatusIndex( gxStatusRecord *pStatus,
- long printerProblem,
- Boolean manualFeed,
- Boolean dontAlert)
- {
- short whichStatResID;
- short whichStatResIndex;
-
- // Extract the statResID and statResIndex values from the printerProblem parameter
-
- whichStatResID = GetStatResID(printerProblem);
- whichStatResIndex = GetStatResIndex(printerProblem);
-
- // The normal settings of statResID and statResIndex are just the values in printerProblem
-
- pStatus->statResId = whichStatResID;
- pStatus->statResIndex = whichStatResIndex;
-
- // Do we need to override the normal settings because we want to suppress an alert or
- // use an alert that's already provided by the Printing Manager?
-
- if (whichStatResID == kTransmissionStatID)
- {
- switch (whichStatResIndex)
- {
- case kOutOfPaperStatIdx:
- if (dontAlert) // T => Don't cause alert to be displayed
- {
- pStatus->statResIndex = kWaitingForPaperStatIdx;
- }
- else // T => We want alert to be displayed; use system supplied alert
- {
- pStatus->statResId = gxUnivAlertStatusResourceId;
- pStatus->statResIndex = (manualFeed) ? gxUnivManualFeedIndex : gxUnivOutOfPaperIndex;
- }
- break;
-
- case kPaperJamStatIdx:
- if (!dontAlert) // T => We want alert to be displayed; use system supplied alert
- {
- pStatus->statResId = gxUnivAlertStatusResourceId;
- pStatus->statResIndex = gxUnivPaperJamIndex;
- }
- break;
-
- case kBadPaperCartridgeStatIdx:
- if (!dontAlert) // T => We want alert to be displayed; use system supplied alert
- {
- pStatus->statResId = gxUnivAlertStatusResourceId;
- pStatus->statResIndex = gxUnivNoPaperTrayIndex;
- }
- break;
-
- case kOpenDoorStatIdx:
- if (dontAlert) // T => We want alert to be displayed; use our alernative non-alert status
- {
- pStatus->statResIndex = kOpenDoorNoAlertStatIdx;
- }
- break;
-
- case kBadTonerCartridgeStatIdx:
- if (dontAlert) // T => We want alert to be displayed; use our alernative non-alert status
- {
- pStatus->statResIndex = kBadTonerCartridgeNoAlertStatIdx;
- }
- break;
- }
- }
- }
- /* SetStatusIndex */
-
-
- /****************************************************************************************
-
- SetStatusBuffer
-
-
- function:
- This routine is called to initialize the contents of the status buffer
- in the status record referenced by pStatus. If we're doing a manual feed
- job and the printer is out of paper, then we set the buffer area to be an
- appropriately initialized ManualFeedRecord structure. If it's not manual feed,
- but the printer is out of paper, then we set buffer area to be a structure of
- size outOfPaperStatusBufferSize.
-
- parameters:
- pStatus Status record used to alert the user to printer problems
- currentProblem the 'stat' ID and res index of the printer's current status
- manualFeed T => doing manual feed job; F => doing auto-feed
- thePaperType the paper type of the paper that should be loaded into the printer
-
- returns:
- None
-
- ****************************************************************************************/
- void SetStatusBuffer(gxStatusRecord *pStatus,
- long printerProblem,
- Boolean manualFeed,
- gxPaperType thePaperType)
- {
- // Determine what info needs to be added to the status record's buffer area
-
- if ( GetStatResIndex(printerProblem) == kOutOfPaperStatIdx )
- {
- if (manualFeed) // T => Fill in the ManualFeedRecord structure with the appropriate paper type info.
- {
- gxManualFeedRecord *mfeedInfo;
-
- mfeedInfo = (gxManualFeedRecord *) &pStatus->statusBuffer;
- mfeedInfo->canAutoFeed = true;
- GXGetPaperTypeName(thePaperType, mfeedInfo->paperTypeName);
- }
- else // T => Fill in the OutOfPaperRecord structure with the appropriate info.
- {
- gxOutOfPaperRecord *outOfPaperInfo;
-
- outOfPaperInfo = (gxOutOfPaperRecord *) &pStatus->statusBuffer;
- GXGetPaperTypeName(thePaperType, outOfPaperInfo->paperTypeName);
- }
- }
- // else - For all other errors, the status buffer area will contain a univStatusBuffer structure
- }
- /* SetStatusBuffer */
-
-
- /****************************************************************************************
-
- ClearStatus
-
-
- function:
- This routine is called to tell the Printing Finder Extension (PFE) to dismiss the
- alert we had displayed. It signals the PFE to dismiss the alert by updating
- the device status to "ready". Anytime the PFE receives a ready status, it
- automatically dismisses the dialog.
-
- parameters:
- pStatus Status record to use in call to AlertTheUser
-
- returns:
- OSErr
-
- ****************************************************************************************/
- OSErr ClearStatus(gxStatusRecord *pStatus)
- {
- OSErr anErr;
- short saveResult = pStatus->dialogResult;
-
- // So that the PFE highlights the ok button before dismissing the dialog, set the
- // dialog result to "ok".
- pStatus->dialogResult = ok;
-
- pStatus->statusOwner = 'univ';
- pStatus->statResId = gxUnivAlertStatusResourceId;
- pStatus->statResIndex = gxUnivPrinterReadyIndex;
-
- // Tell the PFE to remove the alert
- anErr = GXAlertTheUser(pStatus);
-
- // Restore the previous dialog result
- pStatus->dialogResult = saveResult;
-
- return(anErr);
- }
- /* ClearStatus */
-
-
- /****************************************************************************************
-
- CheckPrinter
-
-
- function:
- This routine queries the printer to determine its current status. It returns,
- in the currentProblem parameter, a resource ID and res index into a 'stat'
- resource of the status that reflects the printer's currentstatus. The high
- word of currentProblem contains the 'stat' resource ID of the 'stat' resource
- that indicates the current printer problem, and the low word contains the
- index within the 'stat' resource of the specific printer problem.
-
- parameters:
- pStatus Status record used for alerting the user to the printer problem
- currentProblem returns the 'stat' ID and res index of the printer's current status
- abortPrinting returns true if printer problem is fatal; false otherwise
-
- returns:
- OSErr
-
- ****************************************************************************************/
-
- OSErr CheckPrinter( gxStatusRecord *pStatus,
- long *currentProblem,
- Boolean *abortPrinting)
- {
- OSErr anErr;
- short printerStatus;
- long oldProblem;
-
- *abortPrinting = false;
-
- // Remember the state of the printer from the last time we statused it
- oldProblem = *currentProblem;
-
- // Issue a "Test Unit Ready" command to the printer so that we can get the latest
- // printer status info. when we query it (via a call to FindPrinterProblem).
-
- anErr = LaserSC_GetDeviceStatus(&printerStatus);
- if (anErr == noErr)
- {
- // Is the printer still not ready?
- if (printerStatus != kGoodCondition)
- {
- // Status the printer to determine its current error condition state
- anErr = FindPrinterProblem(currentProblem, abortPrinting);
- if (anErr == noErr)
- {
- // If we've encountered a change in status or the printer is now suffering
- // a fatal error (e.g. hardware problem), then dump the current status alert
- // and return the new status
-
- if ( (oldProblem != *currentProblem) || *abortPrinting )
- {
- // Tell the Printing Finder Extension to dismiss the current alert
- anErr = ClearStatus(pStatus);
- }
- // else - no change in the status and it's not a fatal error
- }
- // else - can't status the printer
- }
- else // T => The printer is now ready
- *currentProblem = kNoPrinterProblem;
- }
- // else - can't issue a "Test Unit Ready" command to the printer
-
- check(anErr == noErr);
- return(anErr);
- }
- /* CheckPrinter */
-
-
- /***************************************************************************************
- * INTERFACE ROUTINES *
- ***************************************************************************************/
-
- /****************************************************************************************
-
- SetPrinterProblemStatResIndex
-
-
- function:
- This is a utility routine for stuffing a 'stat' resource index into the
- low word of a printer problem long word variable. The high word of a printer
- problem variable contains the 'stat' resource ID of the 'stat' resource that
- indicates the current printer problem, and the low word contains the
- index within the 'stat' resource of the specific printer problem.
-
- parameters:
- printerProblem returns long word with statResIndex in the lower word
- statResIndex 'stat' resource index value to stuff into printerProblem
-
- returns:
- None
-
- ****************************************************************************************/
- void SetPrinterProblemStatResIndex(short statResIndex, long *printerProblem)
- {
- short *pShort;
-
- pShort = ((short *) printerProblem) + 1;
- *pShort = statResIndex;
- }
- /* SetPrinterProblemStatResIndex */
-
-
- /****************************************************************************************
-
- SetPrinterProblemStatResID
-
-
- function:
- This is a utility routine for stuffing a 'stat' resource ID into the
- high word of a printer problem long word variable. The high word of a printer
- problem variable contains the 'stat' resource ID of the 'stat' resource that
- indicates the current printer problem, and the low word contains the
- index within the 'stat' resource of the specific printer problem.
-
- parameters:
- printerProblem returns long word with statResID in the high word
- statResID 'stat' resource ID value to stuff into printerProblem
-
- returns:
- None
-
- ****************************************************************************************/
- void SetPrinterProblemStatResID(short statResID, long *printerProblem)
- {
- short *pShort;
-
- pShort = (short *) printerProblem;
- *pShort = statResID;
- }
- /* SetPrinterProblemStatResID */
-
-
- /****************************************************************************************
-
- FindPrinterProblem
-
-
- function:
- This routine is called when the driver has discovered that the LaserWriter SC
- is no longer ready. It calls this routine to determine the reason why the
- printer is not ready. This routine queries the printer to get the latest
- "sense data" from the printer. It then returns a resource ID and res index
- into a 'stat' resource of the status that reflects the printer's current
- status. This index is returned in the printerProblem parameter. The high
- word of printerProblem contains the 'stat' resource ID of the 'stat' resource
- that indicates the current printer problem, and the low word contains the
- index within the 'stat' resource of the specific printer problem.
-
- If the abortPrinting error is non-nil, then this routine will set it to true if
- the error state encountered is one for which we abort printing.
-
- parameters:
- printerProblem returns the 'stat' ID and res index of the printer's current status
- abortPrinting if non-nil, sets to true if printer status causes printing to abort
-
- returns:
- OSErr
-
- ****************************************************************************************/
- OSErr FindPrinterProblem(long *printerProblem, Boolean *abortPrinting)
- {
- OSErr anErr;
- SCSenseData senseData;
- short problemStatResID = kNoPrinterProblem;
- short problemStatResIndex = kNoPrinterProblem;
-
- if (abortPrinting != nil) // Pointer specified so initialize it
- *abortPrinting = false;
-
- // Get the latest status information from the printer
- anErr = LaserSC_GetSenseData(&senseData);
-
- if (anErr == noErr)
- {
- // Is the printer out of paper?
- if ( (senseData.senseKey & kEndOfMedium) == kEndOfMedium )
- {
- problemStatResID = kTransmissionStatID;
- problemStatResIndex = kOutOfPaperStatIdx;
- }
- else
- {
- // What sort of error did we encounter?
- switch ( SenseKey(senseData) )
- {
- case kNotReady:
- CheckEngineStatus0Bits(&senseData, &problemStatResIndex);
-
- if (problemStatResIndex != kNoPrinterProblem)
- problemStatResID = kTransmissionStatID;
- break;
-
- case kMediumError:
- problemStatResID = kTransmissionStatID;
- problemStatResIndex = kPaperJamStatIdx;
- break;
-
- case kHardwareError:
- CheckEngineStatus1Bits(&senseData, &problemStatResIndex);
-
- if (problemStatResIndex != kNoPrinterProblem)
- problemStatResID = kEngineStatusStatID;
-
- if (abortPrinting != nil) // Pointer specified so set it
- *abortPrinting = true;
- break;
-
- case kIllegalRequest:
- check(0); // Illegal command - should never happen in debugged software
- break;
-
- case kUnitAttention:
- // Check the controller status bits for a specific error. If none, flag that the
- // printer reset itself (because it did).
-
- if ( (senseData.controlStatus & kRamFailMask) == kRamFailMask )
- {
- problemStatResID = kEngineStatusStatID;
- problemStatResIndex = kDRamFailureStatIdx;
-
- if (abortPrinting != nil) // Pointer specified so set it
- *abortPrinting = true;
- }
- else
- if ( (senseData.controlStatus & kEngineFailMask) == kEngineFailMask )
- {
- problemStatResID = kEngineStatusStatID;
- problemStatResIndex = kLaserInitFailureStatIdx;
-
- if (abortPrinting != nil) // Pointer specified so set it
- *abortPrinting = true;
- }
- break;
-
- } // switch
- }
- }
-
- // Update the printerProblem parameter with the proper status indicators
-
- SetPrinterProblemStatResIndex(problemStatResIndex, printerProblem);
- SetPrinterProblemStatResID(problemStatResID, printerProblem);
-
- return(anErr);
- }
- /* FindPrinterProblem */
-
-
- /****************************************************************************************
-
- ResolvePrinterProblem
-
-
- function:
- This routine is called to alert the user to a problem with the printer. The
- problem may be one the user can resolve (e.g. out of paper) or one which
- cannot be resolved easily (e.g. hardware problem). For the user correctable
- problems, the user is alerted to the problem and can either fix the problem
- and continue the print job, or cancel the print job. In the case of the
- non-resolvable problems, the user is only given the choice of aborting the
- print job. Also, if a fatal error has occurred, we abort the print job.
-
- The routine uses the AlertTheUser Printing Manager call to display the
- alerts to the user. Whenever possible, we try to use a system defined
- alert (e.g. manual feed) as opposed to one provided by this driver. An
- alert is displayed until all of the printer's problems have been resolved
- or the user aborted printing.
-
- parameters:
- printerProblem high word contains 'stat' res ID corresponding to problem
- low word contains 'stat' res index corresponding to problem
- manualFeed T => doing manual feed job; F => doing auto-feed job
- thePaperType the paper type for the paper that should be placed into
- the printer for manual feed jobs; nil if not manual feed
- dialogResult result (item hit) returned from the dialog when it was dismissed
-
- returns:
- OSErr
-
- ****************************************************************************************/
- OSErr ResolvePrinterProblem( long printerProblem,
- Boolean manualFeed,
- gxPaperType thePaperType,
- short *dialogResult)
- {
-
- OSErr anErr = noErr;
- OSErr anErr2;
- gxStatusRecord *pStatus;
- gxJob theJob = GXGetJob();
- Boolean abortPrinting = false;
- long oldProblem;
- long maxStatusBuffSz;
-
- // Make sure we only display an alert if there has been an error
- require(printerProblem != kNoPrinterProblem, NoPrinterProblem);
-
- // Allocate a status record large enough to handle status with the largest buffer size.
- // Currently the largest record is the max. of the univStatusBuffer, ManualFeedRecord, and OutOfPaperRecord structures.
-
- maxStatusBuffSz = gxOutOfPaperStatusBufferSize;
-
- pStatus = (gxStatusRecord *) NewPtrClear(sizeof(gxStatusRecord) + maxStatusBuffSz);
- anErr = MemError();
- require(anErr == noErr, NewPtrClear);
-
- // Initialize the misc. fields within the status record
- pStatus->bufferLen = maxStatusBuffSz;
- pStatus->statusOwner = 'univ';
-
- // Now we loop with an alert displayed until all the problems are resolved, the
- // user has aborted the print job, or a fatal error has occurred.
- do
- {
- // Initialize the status record's statResID and statResIndex fields based upon the error encountered
- SetStatusIndex(pStatus, printerProblem, manualFeed, false);
-
- // Initialize the contents of the status record buffer based upon the error encountered
- SetStatusBuffer(pStatus, printerProblem, manualFeed, thePaperType);
-
- // Make sure the dialogResult has been reset from some previously displayed dialog (if any)
- pStatus->dialogResult = nil;
-
- // Display the initial error alert and see if the problem resolves itself while alerting
- do
- {
- // Tell the Printing Manager to display the selected alert
-
- anErr = GXAlertTheUser(pStatus);
- if (anErr != noErr)
- break;
-
- // Remember the last printer problem we experienced
- oldProblem = printerProblem;
-
- if (pStatus->dialogResult == nil) // T => No user button action yet
- {
-
- // Pause before doing a status again. If we status too often,
- // the printer gets a bit upset at us.
- WaitForABit();
-
- // Check to see if the printer problem has gone away or is now a different problem
- anErr = CheckPrinter(pStatus, &printerProblem, &abortPrinting);
- if (anErr != noErr)
- break;
-
-
- // If we've now experienced a fatal printer problem (e.g. bad hardware) that is different
- // than the original problem, then alert the user to the problem.
-
- if ( abortPrinting && (oldProblem != printerProblem) )
- {
- // Make sure the previous alert has been dismissed by the Printing Finder Extension
-
- anErr = ClearStatus(pStatus);
- require(anErr == noErr, ClearStatus1);
-
- // Initialize the status record's statResID and statResIndex fields based upon the abort error
- SetStatusIndex(pStatus, printerProblem, manualFeed, false);
-
- // Initialize the contents of the status record buffer based upon the abort error
- SetStatusBuffer(pStatus, printerProblem, manualFeed, thePaperType);
-
- // Make sure the dialogResult has been reset from the previously displayed dialog
- pStatus->dialogResult = nil;
-
- // Display the new fatal error alert until the user acknowledges it
- do
- {
- anErr = GXAlertTheUser(pStatus);
- }
- while ( (pStatus->dialogResult == nil) && (anErr == noErr) );
- }
- // else - not a fatal error or the printer problem hasn't changed
- }
- // else - user hasn't clicked any button yet
- }
- while ((pStatus->dialogResult == nil) && (oldProblem == printerProblem) && (anErr == noErr) );
-
- // At this point there has been some resolution to the problem. The user responded to the
- // alert, the printer problem was fixed at the printer, we got an error checking the status
- // of the printer, or we got an error trying to alert the user. We must always clear status
- // to make sure that the alert is dismissed. Then check for errors.
-
- anErr2 = ClearStatus(pStatus);
- if (anErr2 != noErr)
- {
- if (anErr == noErr)
- anErr == anErr2;
- require(anErr2 == noErr, ClearStatus2);
- }
-
- // If the user has cancelled printing, set the user abort error
- if (pStatus->dialogResult == cancel)
- {
- anErr = gxPrUserAbortErr;
- require(anErr == noErr, UserAborted);
- }
-
- // Did we have a problem statusing the printer or alerting the user?
- require(anErr == noErr, InitialAlertFails);
-
- // Was the original error we displayed a fatal printer problem?
- require(!abortPrinting, PrinterDied);
-
- // If we are in manual feed mode and the user has decided to switch to automatic feed
- // then we will exit. The problem has basically gone away and we'll catch any new problems
- // when the calling routine re-checks to make sure the printer is ready.
-
- if ( (manualFeed) &&
- (GetStatResIndex(printerProblem) == kOutOfPaperStatIdx) &&
- (pStatus->dialogResult == gxAutoFeedButtonId)
- )
- printerProblem = kNoPrinterProblem;
-
-
- // If the user has dismissed the alert but the same problem still remains, we sit
- // in a loop until either the printer problem is resolved or another problem arises. Here
- // the status record passed to AlertTheUser is guaranteed to not generate alerts, because
- // the 'stat' item referenced is not of type userAttention or userAlert.
-
- if ((printerProblem != kNoPrinterProblem) && (oldProblem == printerProblem))
- {
- // Initialize the status record's statResID and statResIndex fields based upon the abort error
- SetStatusIndex(pStatus, printerProblem, manualFeed, true);
-
- // Update the PFE with the new status
-
- anErr = GXAlertTheUser(pStatus);
- require(anErr == noErr, AlertTheUser);
-
- // Keep statusing the printer until the problem is fixed or the problem changes
- do
- {
- // Pause before doing a status again. If we status too often,
- // the printer gets a bit upset at us.
- WaitForABit();
-
- anErr = CheckPrinter(pStatus, &printerProblem, &abortPrinting);
- require(anErr == noErr, CheckPrinter);
-
- // Let the client app have a chance to run
- anErr = GXJobIdle();
- require(anErr == noErr, JobIdleFails);
- }
- while ( (printerProblem != kNoPrinterProblem) && (oldProblem == printerProblem) );
- }
- // else - no longer a printer problem or now it's a different problem
- }
- while (printerProblem != kNoPrinterProblem);
-
- // Make sure the result of displaying the alert is returned
- *dialogResult = pStatus->dialogResult;
-
-
- /******* Clean-up *******/
-
- JobIdleFails:
- CheckPrinter:
- AlertTheUser:
- InitialAlertFails:
- UserAborted:
- ClearStatus2:
- ClearStatus1:
- DisposPtr((Ptr) pStatus);
-
- NewPtrClear:
- NoPrinterProblem:
- return(anErr);
-
- PrinterDied:
- DisposPtr((Ptr) pStatus);
- return(gxPrIOAbortErr);
- }
- /* ResolvePrinterProblem */
-
-